package no.ntnu.item.ttm4115.termproject.gamemanager.configuration;

import java.io.File;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import no.ntnu.item.ttm4115.termproject.extrasagent.SessionOption;
import no.ntnu.item.ttm4115.termproject.extrasagent.SessionQuestion;
import no.ntnu.item.ttm4115.termproject.extrasagent.Treasures;
import no.tellu.common.actorframe.ActorSM;
import no.tellu.common.javaframe.ActorAddress;

public class LoadConfiguration {
	private Vector<Treasures> treasures;

	@SuppressWarnings("unused")
	private ActorSM asm;
	
	

	public LoadConfiguration(ActorSM asm) {
		super();

		this.asm = asm;

		// All the treasure configurations will be loaded from the text file and then treasure
		// vector will be populated
		this.treasures = loadTreasuresFromXMLFile();
	}

	public Vector<Treasures> getTreasures() {
		return treasures;
	}

	public void setTreasures(Vector<Treasures> treasures) {
		this.treasures = treasures;
	}

	/** 
	* Updating the treasure with actor address when it is initialized
	*/
	public void updateTreasure(ActorAddress actorAddress){
		for(Treasures ta:this.getTreasures()){
			if(ta.getActorAddress() == null){
				int index = this.getTreasures().indexOf(ta);
				ta.setActorAddress(actorAddress);
				this.getTreasures().set(index, ta); // replace the old ta with new one at the same index
				break;
			}
		}
		// For debuging purpose ... printing treasure agents having not null actor address
		//printNotNullActorAddressTAs();
	}

	/** 
	 * Printing the available treasures having not null actor address
	 * For test only
	 */
	@SuppressWarnings("unused")
	private void printNotNullActorAddressTAs(){
		System.out.println("Printing non null actoraddress treaure agents");
		for(Treasures ta:this.getTreasures()){
			if(ta.getActorAddress() == null) { }
			else {
				System.out.println("Treasure ActorAddress::: "+ta.getActorAddress()+" name::: "+ta.getName()+" clue::: "+ta.getClue()+" x::: "+ta.getXCoordinate()+" y::: "+ta.getYCoordinate());
			}
		}
	}

	/**
	 * Treasure configurations will be loaded from the XML file and then treasure vector will be populated
	 */
	private Vector<Treasures> loadTreasuresFromXMLFile() {
		treasures = new Vector<Treasures>();
		try {

			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			Document doc = docBuilder.parse (new File("c:/ttm4115config/configGM.xml"));

			// normalize text representation
			doc.getDocumentElement ().normalize ();
			System.out.println ("Root element of the doc is " + doc.getDocumentElement().getNodeName());


			NodeList listOfTreasures = doc.getElementsByTagName("treasure");
			int totalPersons = listOfTreasures.getLength();
			System.out.println("Total no of treasures : " + totalPersons);

			for(int s=0; s<listOfTreasures.getLength() ; s++){

				Node firstPersonNode = listOfTreasures.item(s);
				if(firstPersonNode.getNodeType() == Node.ELEMENT_NODE){

					Element firstPersonElement = (Element)firstPersonNode;

					//-------
					NodeList treasureNameList = firstPersonElement.getElementsByTagName("name");
					Element treasureNameElement = (Element)treasureNameList.item(0);

					NodeList textTNList = treasureNameElement.getChildNodes();
					String treasureName = ((Node)textTNList.item(0)).getNodeValue().trim();
					System.out.println("Loading Treasure Name : " + treasureName);


					//-------loading Clues
					NodeList treasureClueList = firstPersonElement.getElementsByTagName("clue");
					Vector<String> clueTexts = new Vector<String>();
					for(int i = 0; i<treasureClueList.getLength();i++){
					
						Element treasureClueElement = (Element)treasureClueList.item(i);
						NodeList textClueList = treasureClueElement.getChildNodes();
						String treasureClue = ((Node)textClueList.item(0)).getNodeValue().trim();
						clueTexts.add(treasureClue);
						System.out.println("Loading Clue : " + treasureClue);
					}
					

					//----
					NodeList xcorList = firstPersonElement.getElementsByTagName("xcoordinate");
					Element xcorElement = (Element)xcorList.item(0);

					NodeList textXcList = xcorElement.getChildNodes();
					int xCor = Integer.valueOf(((Node)textXcList.item(0)).getNodeValue().trim());
					System.out.println("Loading X-Coordinate : " + xCor);

					//------
					NodeList ycorList = firstPersonElement.getElementsByTagName("ycoordinate");
					Element ycorElement = (Element)ycorList.item(0);

					NodeList textYcList = ycorElement.getChildNodes();
					int yCor = Integer.valueOf(((Node)textYcList.item(0)).getNodeValue().trim());
					System.out.println("Loading Y-Coordinate : " + yCor);

					//------ Loading the questions

					NodeList listOfQuestions = firstPersonElement.getElementsByTagName("question");
					int totalQuestions = listOfQuestions.getLength();
					System.out.println("Total no of Questions : " + totalQuestions);

					Vector<SessionQuestion> questions = new Vector<SessionQuestion>();
					for(int p=0; p<listOfQuestions.getLength() ; p++){
						
						SessionQuestion question = new SessionQuestion();
						Node firstQuestionNode = listOfQuestions.item(p);
						if(firstQuestionNode.getNodeType() == Node.ELEMENT_NODE){

							Element firstQuestionElement = (Element)firstQuestionNode;
							//---- maxPoints
							NodeList maxPointList = firstQuestionElement.getElementsByTagName("maxPoints");
							Element maxPointTextElement = (Element)maxPointList.item(0);
							

							NodeList maxList = maxPointTextElement.getChildNodes();
							int maxPoints = Integer.valueOf(((Node)maxList.item(0)).getNodeValue().trim());
																										
							question.setMaxPoints(maxPoints);
							
							//-------minusPoints
							NodeList minusPointList = firstQuestionElement.getElementsByTagName("minusPoints");
							Element minusPointTextElement = (Element)minusPointList.item(0);
							

							NodeList minusList = minusPointTextElement.getChildNodes();
							int minusPoints = Integer.valueOf(((Node)minusList.item(0)).getNodeValue().trim());
																										
							question.setMinusPoints(minusPoints);
							//------- question text
							NodeList questionTextList = firstQuestionElement.getElementsByTagName("text");
							
							Vector<String> questionsTexts = new Vector<String>();
							for(int i =0; i< questionTextList.getLength(); i++){
									
							Element questionTextElement = (Element)questionTextList.item(i);

							NodeList textList = questionTextElement.getChildNodes();
							String questionText = ((Node)textList.item(0)).getNodeValue().trim();
							System.out.println("Loading QuestionText : " + questionText);
							questionsTexts.add(questionText);
							question.setId(p);
							}
							question.setQuestionText(questionsTexts);
							
							NodeList typeTextList = firstQuestionElement.getElementsByTagName("type");
							Element typeTextElement = (Element)typeTextList.item(0);
							

							NodeList typeList = typeTextElement.getChildNodes();
							String typeText = ((Node)typeList.item(0)).getNodeValue().trim();
																										
							question.setType(typeText);
							System.out.println("Lastet inn question med type " + typeText);
							
							Vector<SessionOption> options = new Vector<SessionOption>();
							//----- options
							NodeList questionOptionList = firstQuestionElement.getElementsByTagName("option");							
							for(int q=0; q<questionOptionList.getLength() ; q++){
								
								SessionOption option = new SessionOption();
								
								Element questionOptionElement = (Element)questionOptionList.item(q);
								NodeList optionList = questionOptionElement.getChildNodes();

								String optionText = ((Node)optionList.item(0)).getNodeValue().trim();
								System.out.println("Loading option "+q+" : " + optionText);
								
								option.setAnswerOption(optionText);
								options.add(option);
								System.out.println("Her kommer Option verdien");
								System.out.println(option.getAnswerOption());
								System.out.println(option.getAnswerOption());
							}
							question.setOptions(options);
							//------- check correctness
							NodeList correctAnswerList = firstQuestionElement.getElementsByTagName("correctanswerindex");
							Element correctAnswerElement = (Element)correctAnswerList.item(0);

							NodeList answerList = correctAnswerElement.getChildNodes();
							int correctAnswerIndex = Integer.valueOf(((Node)answerList.item(0)).getNodeValue().trim());
							System.out.println("Loading correctanswerindex : " + correctAnswerIndex);
							
							question.setCorrectAnswerIndex(correctAnswerIndex);
						}
						
						questions.add(question);
					}

					// Populate the treasure object and add to vector
					treasures.add(new Treasures(null, clueTexts, treasureName, xCor, yCor, questions));
					
				}//end of if clause

				
			}//end of for loop with s var


		}catch (SAXParseException err) {
			System.out.println ("** Parsing error" + ", line " + err.getLineNumber () + ", uri " + err.getSystemId ());
			System.out.println(" " + err.getMessage ());

		}catch (SAXException e) {
			Exception x = e.getException ();
			((x == null) ? e : x).printStackTrace ();

		}catch (Throwable t) {
			t.printStackTrace ();
		}
		//System.exit (0);

		return treasures;
	}
}
